#!/usr/bin/env python3
# encoding=utf-8

import os
import json
import datetime
from chinese_calendar import is_workday
import logging
logger = logging.getLogger(__name__)

baseconfig = {}

def get_base_config(file="config.json"):
    global baseconfig
    # print(baseconfig)
    if len(baseconfig) == 0:
        if os.path.exists(file):
            conf = os.path.join(file)
            logger.info(f"config use {conf}")
        elif os.path.exists(os.path.join('dist', file)):
            conf = os.path.join(os.path.join('dist', file))
            logger.info(f"config use {conf}")
        try:
            with open(conf, 'r', encoding='utf-8') as cf:
                conf = json.load(cf)
        except Exception as e:
            logger.error(f"load json error is [{e}]")
            os._exit(-1)

        if 'docpath' in conf:
            docdir = os.path.abspath(conf['docpath'])
        else:
            docdir = os.path.join(os.path.dirname(__file__), 'doc')
        if not os.path.exists(docdir):
            logger.error(f'请定义正确的文档目录 {docdir}')
            os._exit(-1)
        conf['docpath'] = docdir
            
        if 'mail' not in conf or 'mailtype' not in conf['mail'] or conf['mail']['mailtype'] not in ['pop', 'imap']:
            logger.error('请先定义邮件处理方式 ["pop" / "imap"]')
            os._exit(-1)
        if conf['mail']['mailtype'] == 'pop':
            if 'secpop' not in conf['mail']:
                logger.error('定义邮件处理方式为"pop", 需要定义"secpop"对应邮箱的具体内容')
                os._exit(-1)
            conf['sec'] = conf['mail'].pop('secpop')

        elif conf['mail']['mailtype'] == 'imap':
            if 'secimap' not in conf['mail']:
                logger.error('定义邮件处理方式为"pop", 需要定义"secimap"对应邮箱的具体内容')
                os._exit(-1)
            conf['sec'] = conf['mail'].pop('secimap')
        conf['mailtype'] = conf['mail'].pop('mailtype')
        del conf['mail']
        baseconfig = conf
    else:
        conf = baseconfig
    # print(conf)
    return conf

def get_max_worker():
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    if 'maxworker' in baseconfig and isinstance(baseconfig['maxworker'], int):
        return baseconfig['maxworker']
    return 1

def check_code_in_list(code, stdate, checklist):
    if code in checklist:
        return True
    try:
        code = f'{code}-{stdate.strftime("%Y/%m/%d")}'
        if code in checklist:
            return True
    except Exception as e:
        logger.error(f"check code error [{e}]")
        return False
    return False

def get_doc_fill_base_info(code, stdate, key=None):
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    wordinfo = baseconfig['wordinfo']
    # print(docdir)
    for mkey, mval in wordinfo.items():
        if 'code' not in mval:
            continue
        if check_code_in_list(code, stdate, mval['code']) == False:
            continue
        mkey = mkey.split('suffix_')
        if len(mkey) >=2:
            mkey = mkey[1]
        else:
            mkey = mkey[0]
        if key in mval:
            return (mkey, mval[key])
        return (mkey, mval)
    return (None, None)

def get_doc_dirpath():
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    docdir = baseconfig['docpath']
    # print(docdir)
    return docdir

def get_temp_dirpath():
    tempdir = os.path.join(get_doc_dirpath(), 'temp')
    if not os.path.exists(tempdir):
        os.mkdir(tempdir)
    return tempdir

def get_excel_setting_info(spkey=None):
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    if spkey == None:
        return baseconfig['excelinfo']
    if spkey not in baseconfig['excelinfo']:
        return None
    return baseconfig['excelinfo'][spkey]

def get_filter_info():
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    if 'debugmode' not in baseconfig['filter'] or len(baseconfig['filter']['debugmode']) == 0:
        baseconfig['filter']['debugmode'] = []
    return baseconfig['filter']

def get_sec_info():
    global baseconfig
    if len(baseconfig) == 0:
        get_base_config()
    basedata = baseconfig
    secinfo = {}
    for key, val in basedata['sec'].items():
        secinfo[key] = val
    # logger.info(secinfo)
    return secinfo

def get_product_name_prefix(product, order=0):
    pos = product.find('号')
    if pos < 0:
        return product
    pos = pos + 1
    if order != 0:
        return(product[pos:])
    return(product[:pos])

def get_chart_rules(allrulus, code, stdate):
    noshow = []
    for key, mval in allrulus.items():
        if check_code_in_list(code, stdate, mval) == False:
            continue
        if '不显示_' not in key:
            continue
        noshow.append(key.replace('不显示_', ''))
    return noshow

def get_workday_range(onedate):
    stday = onedate
    while is_workday(stday) == False or stday.weekday() > 4:
        stday = stday - datetime.timedelta(days=1)

    enday = onedate + datetime.timedelta(days=1)
    while is_workday(enday) == False or enday.weekday() > 4:
        enday = enday + datetime.timedelta(days=1)
    enday = enday + datetime.timedelta(hours=23, minutes=59)
    return (stday, enday)

def is_weekend_day(oneday):
    if not isinstance(oneday, datetime.datetime):
        oneday = datetime.datetime.strptime(oneday, "%Y-%m-%d")
    wed = oneday.weekday()
    if wed == 4:
        return True
    if wed > 4:
        return False
    
    for i in range(wed+1, 5):
        oneday = oneday + datetime.timedelta(days=1)
        # logger.info("%s workday:%d wd:%d" % (oneday.strftime("%Y-%m-%d"), calendar.is_workday(oneday), oneday.weekday()))
        if is_workday(oneday) == True:
            return False
    return True
    
def find_origin_excel_date(excelname):
    xlspart = excelname.split('-')
    if len(xlspart) < 2:
        return None
    olddate = ''
    for one in reversed(xlspart[0]):
        if one.isdigit() or one == '.':
            olddate = olddate + one
            continue
        break
    if len(olddate) == 0:
        return None  # 如果没有找到非数字字符
    return ''.join(reversed(olddate))

def email_merge_by_product(emailinfo):
    if len(emailinfo) == 0:
        return None
    maildict = {}
    onelist = []
    pname = emailinfo[0]['name']
    for mail in emailinfo:
        if pname == mail['name']:
            onelist.append(mail)
        else:
            maildict[pname] = onelist
            pname = mail['name']
            onelist = []
            onelist.append(mail)
    if pname not in maildict.keys():
        maildict[pname] = onelist
    return maildict

def get_excel_to_code_info(spcode=None):
    excel2code = get_excel_setting_info('excel2code')
    if excel2code == None:
        return None
    codedict = {}
    for one in excel2code:
        code, spdate = one.split('-')
        if spcode and spcode != code:
            continue
        spdate = datetime.datetime.strptime(spdate, "%Y/%m/%d")
        # spdate = f'{spdate.strftime("%Y.%m.%d")}'
        codedict[code] = spdate
    if len(codedict):
        return codedict
    return None

def get_excel_name_by_emailinfo(one, onlyprefix=0, withspcode=None):
    excelcode = None
    if withspcode:
        excelcode = get_excel_to_code_info(withspcode[0])
    if excelcode:
        prefix = withspcode[1]
    elif 'name' in one:
        prefix = get_product_name_prefix(one['name'])
    else:
        prefix = get_product_name_prefix(one)
    if onlyprefix > 0:
        return prefix
    excellist = []
    for file in os.listdir(get_doc_dirpath()):
        if not file.startswith(prefix + '净值表'):
            if excelcode == None:
                continue
            if not file.startswith(prefix.split('号')[0] + '号净值表'):
                continue
        excellist.append(file)
        if excelcode:
            break
        
    
    if len(excellist) == 0:
        logger.warning(f'请检查文件目录 {prefix} 是否存在')
        # os._exit(-1)
    return excellist


def excel_rename_list_update(xlsinfo, filechlist):
    if 'excel' not in xlsinfo:
        return filechlist
    if 'daterange' not in xlsinfo or len(xlsinfo['daterange']) != 3:
        return filechlist
    xlsname = get_excel_name_by_emailinfo(xlsinfo['excel'], 1)
    xlsname = f'{xlsname}%s-%s.xlsx' % (xlsinfo['daterange'][0].strftime("%Y.%m.%d"), xlsinfo['daterange'][2].replace('-', '.'))
    namedic = {}
    namedic[xlsinfo['excel']] = xlsname
    filechlist.update(namedic)
    return filechlist

def get_sheet_value(sheet, row, col):
    if hasattr(sheet, 'Cells'):
        return sheet.Cells(row, col).Value
    # return sheet.cell(row=row, column=col).value
    return sheet.range((row, col)).value

def get_word_config_str(col, wordmode, key):
    if str(col) not in wordmode:
        return None
    wordmode = wordmode[str(col)]
    if key in wordmode:
        return wordmode[key]
    return None

